// Package api 提供HTTP路由和请求处理功能
// 该包使用Fiber框架来处理HTTP请求和响应
package api

import (
	"aigen-todo/internal/config"
	"aigen-todo/internal/repository"
	"aigen-todo/internal/service"
	"time"

	"github.com/gofiber/fiber/v2"
	"github.com/golang-jwt/jwt/v4"

	"gorm.io/gorm"
)

// 注册认证路由
func registerAuthRoutes(router fiber.Router, db *gorm.DB, cfg *config.Config) {
	// 创建仓库和服务实例
	userRepo := repository.NewUserRepository(db)
	userService := service.NewUserService(userRepo)

	auth := router.Group("/auth")
	{
		auth.Post("/register", RegisterHandler(userService))
		auth.Post("/login", LoginHandler(userService, cfg))
	}
}

// RegisterRequest 定义用户注册请求结构体
type RegisterRequest struct {
	// Username 用户名
	// required: true
	// example: john_doe
	Username string `json:"username" validate:"required"`

	// Email 邮箱地址
	// required: true
	// example: john@example.com
	Email string `json:"email" validate:"required,email"`

	// Password 密码（最少6个字符）
	// required: true
	// example: password123
	Password string `json:"password" validate:"required,min=6"`
}

// LoginRequest 定义用户登录请求结构体
type LoginRequest struct {
	// Username 用户名
	// required: true
	// example: john_doe
	Username string `json:"username" validate:"required"`

	// Password 密码
	// required: true
	// example: password123
	Password string `json:"password" validate:"required"`
}

// RegisterData 定义注册响应中的数据结构
type RegisterData struct {
	UserID    uint64    `json:"user_id"`
	Username  string    `json:"username"`
	Email     string    `json:"email"`
	CreatedAt time.Time `json:"created_at"`
}

// LoginData 定义登录响应中的数据结构
type LoginData struct {
	UserID    uint64    `json:"user_id"`
	Username  string    `json:"username"`
	Token     string    `json:"token"`
	ExpiresAt time.Time `json:"expires_at"`
}

// RegisterHandler 处理用户注册请求
// 该处理器验证注册参数，创建新用户并返回注册结果
// 参数:
//
//	userService - 用户服务实例
//
// 返回值:
//
//	fiber.Handler - Fiber处理函数
func RegisterHandler(userService *service.UserService) fiber.Handler {
	return func(c *fiber.Ctx) error {
		// 绑定JSON请求数据到RegisterRequest结构体
		var req RegisterRequest
		if err := c.BodyParser(&req); err != nil {
			return BadRequest(c) // 使用默认错误消息
		}

		// 调用用户服务注册新用户
		user, err := userService.Register(req.Username, req.Email, req.Password)
		if err != nil {
			if err == service.ErrUserAlreadyExists {
				return Conflict(c) // 使用默认错误消息
			} else {
				return InternalServerError(c) // 使用默认错误消息
			}
		}

		// 返回注册成功的响应
		data := RegisterData{
			UserID:    user.ID,
			Username:  user.Username,
			Email:     user.Email,
			CreatedAt: user.CreatedAt,
		}
		return SuccessWithMessage(c, "注册成功", data)
	}
}

// LoginHandler 处理用户登录请求
// 该处理器验证登录凭据，生成JWT令牌并返回登录结果
// 参数:
//
//	userService - 用户服务实例
//	cfg - 应用程序配置
//
// 返回值:
//
//	fiber.Handler - Fiber处理函数
func LoginHandler(userService *service.UserService, cfg *config.Config) fiber.Handler {
	return func(c *fiber.Ctx) error {
		// 绑定JSON请求数据到LoginRequest结构体
		var req LoginRequest
		if err := c.BodyParser(&req); err != nil {
			return BadRequest(c) // 使用默认错误消息
		}

		// 调用用户服务验证登录凭据
		user, err := userService.Login(req.Username, req.Password)
		if err != nil {
			if err == service.ErrInvalidCredentials {
				return Unauthorized(c) // 使用默认错误消息
			} else {
				return InternalServerError(c) // 使用默认错误消息
			}
		}

		// 生成JWT令牌
		token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
			"user_id": user.ID,
			"exp":     time.Now().Add(time.Hour * 24).Unix(),
		})

		// 使用配置中的密钥签名令牌
		tokenString, err := token.SignedString([]byte(cfg.JWT.Secret))
		if err != nil {
			return InternalServerError(c) // 使用默认错误消息
		}

		// 返回登录成功的响应，包含JWT令牌
		data := LoginData{
			UserID:    user.ID,
			Username:  user.Username,
			Token:     tokenString,
			ExpiresAt: time.Now().Add(time.Hour * 24),
		}
		return SuccessWithMessage(c, "登录成功", data)
	}
}
